package com.kakavr.util;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.kakavr.base.log.BaseLog;

/**
 * json和对象之间转换
 * @author yang gang
 *
 */
public class ConvertUtils extends BaseLog {

	public static String toJson(Map<String, Object> map) {
		JSONObject jsonObj = new JSONObject();
		contructMapData(jsonObj, map);
		return jsonObj.toString();
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private static void contructMapData(JSONObject jsonObj,
			Map<String, Object> map) {
		for (Map.Entry<String, Object> entry : map.entrySet()) {
			String key = entry.getKey();
			Object val = entry.getValue();
			if (val instanceof Date) {
				val = DateTimeUtils.dateToTimePattern((Date) val);
				jsonObj.put(key, val);
			} else if (val instanceof Map) {
				JSONObject _jsonObj = new JSONObject();
				jsonObj.put(key, _jsonObj);
				contructMapData(_jsonObj, (Map) val);
			} else if (val instanceof List) {
				JSONArray arr = new JSONArray();
				jsonObj.put(key, arr);
				contructMapData(arr, (List) val);
			} else {
				jsonObj.put(key, val);
			}
		}
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private static void contructMapData(JSONArray jsonArr, List list) {
		for (Object val : list) {
			if (val instanceof Date) {
				val = DateTimeUtils.dateToTimePattern((Date) val);
				jsonArr.add(val);
			} else if (val instanceof Map) {
				JSONObject _jsonObj = new JSONObject();
				jsonArr.add(_jsonObj);
				contructMapData(_jsonObj, (Map) val);
			} else if (val instanceof List) {
				JSONArray arr = new JSONArray();
				jsonArr.add(arr);
				contructMapData(arr, (List) val);
			} else {
				jsonArr.add(val);
			}
		}
	}

	public static String POToJson(Object o) {
		return JSONObject.toJSONString(o);
	}

	public static Map<String, Object> jsonToMap(String json) {
		Map<String, Object> map = Maps.<String, Object> newHashMap();
		if (StringUtils.isNotBlank(json)) {
			JSONObject jsonObj = JSONObject.parseObject(json);
			constuctJsonObj(map, jsonObj);
		}
		return map;
	}

	@SuppressWarnings("rawtypes")
	private static void constuctJsonObj(Map<String, Object> map,
			JSONObject jsonObj) {
		Iterator iter = jsonObj.keySet().iterator();
		while (iter.hasNext()) {
			String key = iter.next().toString();
			Object obj = jsonObj.get(key);
			if (obj instanceof JSONObject) {
				Map<String, Object> childMap = Maps
						.<String, Object> newHashMap();
				map.put(key, childMap);
				constuctJsonObj(childMap, (JSONObject) obj);
			} else if (obj instanceof JSONArray) {
				List list = Lists.newArrayList();
				map.put(key, list);
				constructJsonArray(list, (JSONArray) obj);
			} else {
				map.put(key, obj);
			}
		}
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private static void constructJsonArray(List list, JSONArray array) {
		for (Object obj : array) {
			if (obj instanceof JSONArray) {
				List childList = Lists.newArrayList();
				list.add(childList);
				constructJsonArray(childList, (JSONArray) obj);
			} else if (obj instanceof JSONObject) {
				Map<String, Object> map = Maps.newHashMap();
				list.add(map);
				constuctJsonObj(map, (JSONObject) obj);
			} else {
				list.add(obj);
			}
		}
	}
}
